package com.motu.monstercity.server.game.web;


import com.google.protobuf.Message.Builder;
import com.googlecode.protobuf.format.JsonFormat;
import com.motu.monstercity.module.common.network.RequestParam;
import com.motu.monstercity.protocol.CsGameTest.CSGameTestServerResponse;
import com.motu.monstercity.server.game.verticle.MainVerticle;
import com.motu.vertx.module.utility.exception.LockException;
import com.motu.vertx.module.utility.toolset.ErrorWord;
import com.motu.vertx.module.utility.toolset.Tool;
import com.motu.vertx.module.utility.webtool.BaseWebHandler;
import io.vertx.core.json.JsonArray;
import io.vertx.core.json.JsonObject;
import io.vertx.ext.web.RoutingContext;
import io.vertx.ext.web.client.WebClient;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

public class ProtobufHandler extends BaseWebHandler {
    private final static Logger logger = LoggerFactory.getLogger(ProtobufHandler.class);

    // 获取协议命令列表
    public static void getCmdList(RoutingContext routingContext, JsonObject json, String adminName, WebClient client) {
        int start = 70101;
        int end = 99999;
        sendHttpResponse(routingContext.response(), new JsonObject().put("cmds", ProtobufManager.getCmdList(start, end)));
    }

    // 获取协议参数
    public static void getCmdParams(RoutingContext routingContext, JsonObject json, String adminName, WebClient client) {
        String cmd = json.getString("cmd");
        JsonArray jsonArray = ProtobufManager.getParams(cmd);
        sendHttpResponse(routingContext.response(), new JsonObject().put("params", jsonArray));
    }

    // 执行协议命令
    public static void executeCmd(RoutingContext routingContext, JsonObject json, String adminName, WebClient client) {
        //System.out.println("#####executeCmd params:" + json.toString());
        String cmdName = json.getString("cmd");
        long userId = json.getLong("userid");
        int cmdCode = json.getInteger("code");
        JsonObject params = json.getJsonObject("params");
        Builder builder = ProtobufManager.getRequestBuild(cmdName, 0);
        if (builder == null) {
            sendHttpResponseError(routingContext.response(), "调试命令没有配置");
        }
        try {
            JsonFormat.merge(params.toString(), builder);
            byte[] pbdata = builder.build().toByteArray();
            RequestParam requestParam = new RequestParam(userId, (byte)0, pbdata);// 构建请求参数
            Class<?> threadClazz;
            String strClass = ProtobufManager.getHandlerNameByCmd(cmdName);
            String packetPath = "com.motu.monstercity.server.game.logichandler.";
            threadClazz = Class.forName(packetPath + strClass);
            Method method = threadClazz.getMethod(cmdName,  new Class[] {RequestParam.class});// 找到对应的方法
            Object result = method.invoke(null, new Object[] {requestParam});// 反射执行
            if (result instanceof Enum) {
                ErrorWord er = (ErrorWord)result;
                sendHttpResponse(routingContext.response(), new JsonObject().put("ret", er.value));// 错误码
            } else {
                Builder tmp = (Builder) result;
                byte[] responseData = tmp.build().toByteArray();
                Builder res_build = ProtobufManager.getResponseBuild(cmdName, 0);
                res_build.mergeFrom(responseData);
                String responseJson = JsonFormat.printToString(res_build.build());
                //System.out.println("#####executeCmd cmd:" + cmdName + " response:" + responseJson);
                sendHttpResponse(routingContext.response(), new JsonObject().put("data", responseJson));// 成功返回json数据
            }
        } catch (InvocationTargetException e) {
            Throwable t = e.getTargetException();// 获取反射目标异常
            String errMsg = Tool.getException(t);
            logger.error(errMsg);
            if (t instanceof LockException){
                sendHttpResponseError(routingContext.response(), "获取锁超时");
            } else{
                sendHttpResponseError(routingContext.response(), "解析参数失败");
            }
        } catch (Exception e){
            logger.error(e.getMessage());
            sendHttpResponseError(routingContext.response(), "解析参数失败");
        }
    }
}
